/*
 * create:2016年4月15日 下午1:13:32
 * author:wangds  
 */
package com.cxkj.shop.biz;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import com.cxkj.shop.form.DefaultDelivery;
import com.cxkj.shop.form.Delivery;
import com.cxkj.shop.model.balance.BalanceOwner;
import com.cxkj.shop.model.order.DefaultOrder;
import com.cxkj.shop.model.order.DefaultOrderItem;
import com.cxkj.shop.model.order.Order;
import com.cxkj.shop.model.order.OrderItem;
import com.cxkj.shop.model.shoppingcart.CommodityItem;
import com.cxkj.shop.model.shoppingcart.ShoppingCart;
import com.cxkj.shop.model.shoppingcart.ShoppingCartUtils;
import com.cxkj.shop.model.user.User;
import com.cxkj.shop.proc.AbstractWithResMybatisProc;
import com.cxkj.shop.utils.BusinessUtils;
import com.cxkj.shop.utils.DictUtils;
import com.cxkj.shop.utils.UserUtils;

import net.wangds.comp.business.http.AbstractHttpInteractionBusiness;

/**
 * 从购物车创建一个订单.
 * @author wangds
 *
 */
public class CreateNewOrderBusiness extends AbstractHttpInteractionBusiness<Map<String,Object>, Delivery> {

  private AbstractWithResMybatisProc<Order,Integer> orderProc = null;
  
  /**
   * The getter method of the property orderProc.
   * @author wangds 2016年4月15日 下午2:26:08.
   * @return the orderProc.
   */
  public AbstractWithResMybatisProc<Order, Integer> getOrderProc() {
    return orderProc;
  }

  /**
   * The setter method of the property orderProc.
   * @param theorderProc the orderProc to set
   * @author wangds 2016年4月15日 下午2:26:08.
   */
  public void setOrderProc(AbstractWithResMybatisProc<Order, Integer> orderProc) {
    this.orderProc = orderProc;
  }

  /*
   * @see net.wangds.common.processor.Processor#process()
   * @author wangds 2016年4月15日 下午1:14:15.
   */
  @SuppressWarnings("unchecked")
  @Override
  public void process() throws Exception {
    DefaultDelivery<Object> res = new DefaultDelivery<>();
    Map<String, Object> form = this.getInput();
    Map<String, Object> form_address = (Map<String, Object>)form.get("address");
    String wantTime = String.valueOf(form.get("wantTime"));
    
    Order order = createOrder();
    fillOrderPostAddress(form_address, order);
    order.setWantTime(wantTime);
    

    HttpSession ssn=BusinessUtils.getHttpSessionFromHttpBusiness(this);
    User user = UserUtils.selectUserByOpenId(BusinessUtils.getOpenIdSession(ssn));
    if(user.getStatus()==User.STATUS_VIP){
      order.setFavor(DictUtils.loadVipFavor());
    }
    
    int p0 = order.getTotal()-order.getFree();
    
    int favor = ((Number)(Math.ceil((float)p0*order.getFavor()/100))).intValue();
    
    if(user instanceof BalanceOwner){
      BalanceOwner<Integer> o = (BalanceOwner<Integer>)user;
      int bal = o.getBalance();
      if(bal>0){
        int order_max_balance=p0-favor;
        if(bal>=order_max_balance){
          order.setBalance(order_max_balance);
        }else{
          order.setBalance(bal);
        }
      }
    }
    order.setVip(favor);
    order.setPay(p0-favor-order.getBalance());
    
    this.orderProc.setParameter(order);
    this.orderProc.process();
    
    boolean proc_res = this.orderProc.getResult()>=0;
    if(proc_res){
      res.setData(order);
      
      ShoppingCart cart = BusinessUtils.getShoppingCartFromSession(ssn);
      ShoppingCartUtils.clear(cart);
    }
    res.setSuccess(proc_res);
    res.setPostTs(System.currentTimeMillis());
    
    this.setResult(res);
  }

  /**
   * .
   * @author wangds 2016年4月15日 下午1:44:16.
   * @param form_address
   * @param order
   */
  protected void fillOrderPostAddress(Map<String, Object> form_address, Order order) {
    order.setAddress(String.valueOf(form_address.get("address")));
    order.setPhone(String.valueOf(form_address.get("phone")));
    order.setPostCode(String.valueOf(form_address.get("postCode")));
    order.setReceiverName(String.valueOf(form_address.get("receiverName")));
  }

  /**
   * .
   * @author wangds 2016年4月15日 下午1:29:44.
   * @return 
   */
  protected Order createOrder() {
    DefaultOrder res = new DefaultOrder();
    HttpSession ssn = BusinessUtils.getHttpSessionFromHttpBusiness(this);
    ShoppingCart cart = BusinessUtils.getShoppingCartFromSession(ssn);
    
    res.setOrderId(BusinessUtils.newOrderId());
    res.setOpenId(BusinessUtils.getOpenIdSession(ssn));
    res.setCreateTm(System.currentTimeMillis());
    
    int total = 0;
    int total_score = 0;
    Collection<CommodityItem> cart_items = ShoppingCartUtils.fetchCommodities(cart);
    List<OrderItem> items = new LinkedList<OrderItem>();
    for(CommodityItem item:cart_items){
      DefaultOrderItem oitem = new DefaultOrderItem();
      oitem.setOrderId(res.getOrderId());
      oitem.setCommodityId(item.getCommodityId());
      oitem.setCommodityName(item.getCommodityName());
      oitem.setCommodityCode(item.getCommodityCode());
      int price = item.getPrice();
      oitem.setPrice(price);
      oitem.setAmount(item.getAmount());
      oitem.setScore(item.getScore());
      oitem.setGprice(0);
      oitem.setGscore(0);
      oitem.setLprice(0);
      oitem.setLscore(0);
      oitem.setGrouppayId(0);
      oitem.setTimelimitpayId(0);
      oitem.setType(CommodityItem.TYPE_COMMODITY);
      
      int freeType = item.getFreeType();
      
      oitem.setFreeType(freeType);
      
      if(freeType!=CommodityItem.TYPE_NO_FREE){//赠品金额
        res.setFree(price);
      }
      
      total+=(oitem.getPrice()*oitem.getAmount());
      total_score+=(oitem.getScore()*oitem.getAmount());
      items.add(oitem);
    }
    
    cart_items = ShoppingCartUtils.fetchGroupPayments(cart);
    for(CommodityItem item:cart_items){
      DefaultOrderItem oitem = new DefaultOrderItem();
      oitem.setOrderId(res.getOrderId());
      oitem.setCommodityId(item.getCommodityId());
      oitem.setCommodityName(item.getCommodityName());
      oitem.setCommodityCode(item.getCommodityCode());
      oitem.setPrice(item.getPrice());
      oitem.setAmount(item.getAmount());
      oitem.setScore(item.getScore());
      oitem.setGprice(item.getGprice());
      oitem.setGscore(item.getGscore());
      oitem.setLprice(0);
      oitem.setLscore(0);
      oitem.setGrouppayId(item.getGrouppayId());
      oitem.setTimelimitpayId(0);
      oitem.setType(CommodityItem.TYPE_GROUP_PAY);
      total+=(oitem.getGprice()*oitem.getAmount());
      total_score+=(oitem.getGscore()*oitem.getAmount());
      items.add(oitem);
    }
    
    cart_items = ShoppingCartUtils.fetchTimeLimitPayments(cart);
    for(CommodityItem item:cart_items){
      DefaultOrderItem oitem = new DefaultOrderItem();
      oitem.setOrderId(res.getOrderId());
      oitem.setCommodityId(item.getCommodityId());
      oitem.setCommodityName(item.getCommodityName());
      oitem.setCommodityCode(item.getCommodityCode());
      oitem.setPrice(item.getPrice());
      oitem.setAmount(item.getAmount());
      oitem.setScore(item.getScore());
      oitem.setGprice(0);
      oitem.setGscore(0);
      oitem.setLprice(item.getLprice());
      oitem.setLscore(item.getLscore());
      oitem.setGrouppayId(0);
      oitem.setTimelimitpayId(item.getTimelimitpayId());
      oitem.setType(CommodityItem.TYPE_TIME_LIMIT_PAY);
      total+=(oitem.getLprice()*oitem.getAmount());
      total_score+=(oitem.getLscore()*oitem.getAmount());
      items.add(oitem);
    }
    
    cart_items = ShoppingCartUtils.fetchScorePayments(cart);
    for(CommodityItem item:cart_items){
      DefaultOrderItem oitem = new DefaultOrderItem();
      oitem.setOrderId(res.getOrderId());
      oitem.setCommodityId(item.getCommodityId());
      oitem.setCommodityName(item.getCommodityName());
      oitem.setCommodityCode(item.getCommodityCode());
      oitem.setPrice(item.getPrice());
      oitem.setAmount(item.getAmount());
      oitem.setScore(item.getScore());
      oitem.setGprice(0);
      oitem.setGscore(0);
      oitem.setLprice(0);
      oitem.setLscore(0);
      oitem.setGrouppayId(0);
      oitem.setTimelimitpayId(0);
      oitem.setType(CommodityItem.TYPE_SCORE_PAY);
      total+=(oitem.getPrice()*oitem.getAmount());
      total_score+=(oitem.getScore()*oitem.getAmount());
      items.add(oitem);
    }
    
    
    res.setItems(items);
    res.setTotal(total);
    res.setTotalScore(total_score);
    return res;
  }

}
